import { Dialog, Typography } from '@mui/material';
import { useEffect, useState } from 'react';

import Disbursement from '../../api/disbursement/disbursement';
import DisbursementManager from '../../api/disbursement/disbursement-manager';
import { Network } from '../../api/token/token-manager';
import Transaction from '../../api/transaction/transaction';
import TransactionManager from '../../api/transaction/transaction-manager';
import { DisbursementFlow, DisbursementType } from '../../constants/disbursement-flow';
import styles from '../../styles/components/index/progress-popup.module.css';
import PopupTransition from '../shared/dialogs/UIs/popup-transition';
import ProgressBar from '../shared/progress-bar';

export interface SaveDisbursementPopupProps {
    transactions: Array<Transaction>;
    title: string;
    token: string;
    type: DisbursementType;
    network: Network;
    updateFlow: Function;
}

export default function SaveDisbursementPopup(props: SaveDisbursementPopupProps) {
    const [disbursement, setDisbursement] = useState(null);
    const [done, setDone] = useState(false);

    useEffect(() => {
        save().then();
    }, []);

    useEffect(() => {
        if (!done) {
            check(disbursement).then();
        }
    }, [done]);

    const save = async () => {
        let disbursement = new Disbursement();
        disbursement.title = props.title;
        disbursement.currency = props.token;
        disbursement.network = props.network.id;
        disbursement.saved = 0;
        disbursement.processed = 0;
        disbursement.total = props.transactions.length;
        disbursement.type = props.type;
        setDisbursement(disbursement);

        disbursement = await DisbursementManager.save(disbursement);
        setDisbursement(disbursement);

        let i = 0;
        const size = 10;

        while (i < props.transactions.length) {
            try {
                const batch = props.transactions.slice(i, i + size);
                const updated = await TransactionManager.save(disbursement.id, batch);

                if (updated != null) {
                    setDisbursement(updated);
                    i += size;
                }

                await new Promise((r) => setTimeout(r, 50));
            } catch (exception) {
                console.log(exception);
            }
        }

        check(disbursement);
    };

    const check = async (disbursement: Disbursement) => {
        if (!done) {
            if (disbursement) {
                try {
                    const updated = await DisbursementManager.getProgress(disbursement.id);
                    if (updated.saved >= disbursement.saved) {
                        setDisbursement(updated);

                        if (updated.saved < updated.total) {
                            await new Promise((r) => setTimeout(r, 1000));
                            setDone(false);
                        }
                        props.updateFlow(DisbursementFlow.CONFIRM, disbursement);
                        setDone(true);
                    }
                } catch (exception) {
                    console.log(exception);
                    setDone(true);
                }
            }
        }
    };

    const getSavedProgress = () => {
        if (disbursement != null) {
            return (disbursement.saved / disbursement.total) * 100;
        }

        return 0;
    };

    return (
        <div>
            <Dialog
                open={!done}
                TransitionComponent={PopupTransition}
                keepMounted
                aria-describedby="alert-dialog-slide-description"
                className={styles['popup']}
            >
                <div className={styles['popup-content']}>
                    <Typography variant="h5" align="center">
                        {disbursement && disbursement.title
                            ? disbursement.title
                            : 'Processing Disbursement'}
                    </Typography>

                    <ProgressBar progress={getSavedProgress()} />

                    <Typography variant="caption" display="block" className="top-10" align="center">
                        {disbursement ? disbursement.saved : ''} of{' '}
                        {disbursement ? disbursement.total : ''}{' '}
                        {disbursement && disbursement.total !== 1 ? 'transactions' : 'transaction'}{' '}
                        saved
                    </Typography>

                    <Typography variant="body2" className="top-30" align="center">
                        Please wait while we save your transactions...
                    </Typography>
                </div>
            </Dialog>
        </div>
    );
}
